/**
 * Copyright 2008-2009. Chongqing Communications Industry Services Co.,Ltd Information Technology Branch. All rights
 * reserved. <a>http://www.cqcis.com</a>
 */
package com.cqcis.uip.base.framework.core.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import com.cqcis.uip.base.framework.common.Task;
import com.cqcis.uip.base.framework.core.TaskWaitTimeConsumePool;
import com.cqcis.uip.base.framework.core.TaskWaitTimeoutExecutor;
import com.cqcis.uip.base.framework.utils.TaskUtil;

/**
 * Task等待池实现
 * 
 * @author huangmy
 * @date   2008-5-9
 */
public class TaskWaitTimeConsumePoolImpl implements TaskWaitTimeConsumePool, Runnable {		
    private TaskWaitTimeoutExecutor handlerIfTimeout; // 超时应该执行的句柄
    private Map<Task, TimeConsumeDescriptor> timewaiters = new ConcurrentHashMap<Task, TimeConsumeDescriptor>();
    
    public TaskWaitTimeConsumePoolImpl(TaskWaitTimeoutExecutor handlerIfTimeout) {
    	this.handlerIfTimeout = handlerIfTimeout;
    }
    
    public void run() {    	
    	synchronized (this.timewaiters) {
    		doTimewaitPoolCheck();
		}
    }
    
    /**
     * 检测操作
     * 
     */
    private void doTimewaitPoolCheck() {
    	if (this.timewaiters.isEmpty() || this.timewaiters.size() <= 0) {
    		return;
    	}
    	
    	List<Task> removeTasks = new ArrayList<Task>();    	
    	for (Entry<Task, TimeConsumeDescriptor> entry : this.timewaiters.entrySet()) {			
			Task task = entry.getKey();
			TimeConsumeDescriptor tcd = entry.getValue();
			
			if (tcd.isTimeout()) { // 超时
				TaskUtil.removeWaitTimePool(task);
				TaskUtil.removeTimeoutWaitState(task);
				
				this.handlerIfTimeout.execute(task);
				removeTasks.add(task);
			}
		}
    	
    	for (Task task : removeTasks) {
    		this.timewaiters.remove(task);
    	}
    }
    
    public boolean removeTaskWaitAndExecute(Task task) {    	
    	if (removeTaskWait(task)) {
    		TaskUtil.removeTimeoutWaitState(task);
    		
    		this.handlerIfTimeout.execute(task);
    		return true;
    	}
    	return false;
    }
    
    public boolean removeTaskWait(Task task) {    	
    	if (this.timewaiters.remove(task) != null) {
    		TaskUtil.removeTimeoutWaitState(task);
    		return true;
    	}
    	return false;
    }

	public Collection<Task> getAllTaskWaits() {		
		return timewaiters.keySet();
	}

	public void putTaskWait(Task task) {		
		timewaiters.put(task, new TimeConsumeDescriptor(task.getWaitTime()));
		TaskUtil.setTimeoutWaitState(task);
	}

	public Task removeTaskWait() {
		Task task = null;
		for (Entry<Task, TimeConsumeDescriptor> entry : timewaiters.entrySet()) {			
			task = entry.getKey();
			break;
		}
		if (task != null) {
			timewaiters.remove(task);
			TaskUtil.removeTimeoutWaitState(task);
			TaskUtil.removeWaitTimePool(task);
		}
				
		return task;
	}
    
	/**
	 * 时间消耗描述
	 * 
	 * @author huangmy
	 * @date   2008-5-9
	 */
	class TimeConsumeDescriptor {
		private long totalTimewait; // 等待时间总数
		private long beginTime; // 开始计时时间
		
		public TimeConsumeDescriptor(long totalTimewait) {
			this.totalTimewait = totalTimewait;
			this.beginTime = System.currentTimeMillis();
		}

		/**
		 * 是否超时
		 * 
		 * @return
		 */
		public boolean isTimeout() {
			long ct = System.currentTimeMillis();
			return ((ct - this.beginTime) >= this.totalTimewait) ? true : false;
		}
	}
}
